package com.jason.fontmetrics.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

/**
 * @DESC:   StaticLayout是android.text.Layout的一个子类，
 *          很明显它也是为文本处理量身定做的，其内部实现了文本绘制换行的处理
 * @Author: Jason
 * @Date: 16/8/29
 * @Time: 21:20
 *
 *
 * Paint的一些方法:
 *          1.ascent()
 *              返回上坡度的值
 *          2.descent()
 *              返回下坡度的值
 *          3.breakText (CharSequence text, int start, int end, boolean measureForwards, float maxWidth, float[] measuredWidth)
 *              这个方法让我们设置一个最大宽度在不超过这个宽度的范围内返回实际测量值否则停止测量，参数很多但是都很好理解，text表示我们的字符串，
 *              start表示从第几个字符串开始测量，end表示从测量到第几个字符串为止，measureForwards表示向前还是向后测量，
 *              maxWidth表示一个给定的最大宽度在这个宽度内能测量出几个字符，measuredWidth为一个可选项，
 *              可以为空，不为空时返回真实的测量值。
 *              同样的方法还有breakText (String text, boolean measureForwards, float maxWidth,
 *              float[] measuredWidth)和breakText (char[] text, int index, int count, float maxWidth, float[] measuredWidth)。
 *              这些方法在一些结合文本处理的应用里比较常用，
 *              比如文本阅读器的翻页效果，我们需要在翻页的时候动态折断或生成一行字符串，这就派上用场了
 *
 *          4.getFontMetrics (Paint.FontMetrics metrics)
 *              这个和我们之前用到的getFontMetrics()相比多了个参数，getFontMetrics()返回的是FontMetrics对象
 *              而getFontMetrics(Paint.FontMetrics metrics)返回的是文本的行间距，如果metrics的值不为空则返回FontMetrics对象的值。
 *
 *          5.getFontMetricsInt()
 *              该方法返回了一个FontMetricsInt对象，FontMetricsInt和FontMetrics是一样的，
 *              只不过FontMetricsInt返回的是int而FontMetrics返回的是float
 *
 *          6.getFontMetricsInt(Paint.FontMetricsInt fmi)
 *
 *          7.getFontSpacing()
 *              返回字符行间距
 *
 *          8.setUnderlineText(boolean underlineText)
 *              设置下划线
 *
 *          9.setTypeface(Typeface typeface)
 *              设置字体类型，上面我们也使用过，Android中字体有四种样式：
 *              BOLD（加粗）,BOLD_ITALIC（加粗并倾斜）,ITALIC（倾斜）,NORMAL（正常）
 *              而其为我们提供的字体有五种：DEFAULT,DEFAULT_BOLD,MONOSPACE,SANS_SERIF和SERIF，
 *              这些什么类型啊、字体啊之类的都很简单大家自己去试试就知道就不多说了。
 *              但是系统给我们的字体有限我们可不可以使用自己的字体呢？答案是肯定的！
 *              Typeface这个类中给我们提供了多个方法去个性化我们的字体
 *
 *          10.defaultFromStyle(int style)
 *              简而言之就是把上面所说的四种Style封装成Typeface
 *
 *          11.create(String familyName, int style)和create(Typeface family, int style)
 *              textPaint.setTypeface(Typeface.create("SERIF", Typeface.NORMAL));
 *              textPaint.setTypeface(Typeface.create(Typeface.SERIF, Typeface.NORMAL));
 *
 *          12. createFromAsset(AssetManager mgr, String path)、
 *              createFromFile(String path)和 createFromFile(File path)
 *                  这三者也是一样的，它们都允许我们使用自己的字体比如我们从asset目录读取一个字体文件：
 *                  // 获取字体并设置画笔字体
 *                  Typeface typeface = Typeface.createFromAsset(context.getAssets(), "kt.ttf");
 *                  textPaint.setTypeface(typeface);
 *
 *
 *          13.setTextSkewX(float skewX)
 *              设置文本在水平方向上的倾斜  textPaint.setTextSkewX(-0.25F);
 *              这个倾斜值没有具体的范围，但是官方推崇的值为-0.25可以得到比较好的倾斜文本效果，值为负右倾值为正左倾，默认值为0
 *
 *          14.setTextSize (float textSize)
 *              该值必须大于0
 *
 *          15.setTextScaleX (float scaleX)
 *              将文本沿X轴水平缩放，默认值为1，当值大于1会沿X轴水平放大文本，当值小于1会沿X轴水平缩放文本
 *              setTextScaleX不仅放大了文本宽度同时还拉伸了字符
 *
 *          16.setTextLocale (Locale locale)
 *              设置地理位置
 *
 *          17.setTextAlign (Paint.Align align)
 *              设置文本的对其方式，可供选的方式有三种：CENTER,LEFT和RIGHT，其实从这三者的名字上看我们就知道其意思，
 *              但是问题是这玩意怎么用的？好像没什么用啊……我们的文本大小是通过size和typeface确定的
 *              （其实还有其他的因素但这里影响不大忽略~~），一旦baseline确定，对不对齐好像不相干吧……但是，
 *              你要知道一点，文本的绘制是从baseline开始没错，但是是从哪边开始绘制的呢？左端还是右端呢？
 *              而这个Align就是为我们定义在baseline绘制文本究竟该从何处开始，
 *              上面我们在进行对文本的水平居中时是用Canvas宽度的一半减去文本宽度的一半
 *
 *          18.setSubpixelText (boolean subpixelText)
 *              设置是否打开文本的亚像素显示
 *
 *          19.setStrikeThruText (boolean strikeThruText)
 *              文本删除线
 *
 *          20.setLinearText (boolean linearText)
 *              设置是否打开线性文本标识，这玩意对大多数人来说都很奇怪不知道这玩意什么意思。
 *              想要明白这东西你要先知道文本在Android中是如何进行存储和计算的。在Android中文本的绘制需要使用一个bitmap作为单个字符的缓存，
 *              既然是缓存必定要使用一定的空间，我们可以通过setLinearText (true)告诉Android我们不需要这样的文本缓存。
 *
 *          21.setFakeBoldText (boolean fakeBoldText)
 *              设置文本仿粗体
 *
 *          22.measureText (String text),measureText (CharSequence text, int start, int end),
 *             measureText (String text, int start, int end),measureText (char[] text, int index, int count)
 *
 *          23.setDither(boolean dither)
 *              绘制图像时的抗抖动
 *
 *          24.setMaskFilter(MaskFilter maskfilter)
 *              MaskFilter类中没有任何实现方法，而它有两个子类BlurMaskFilter和EmbossMaskFilter，
 *              前者为模糊遮罩滤镜（比起称之为过滤器哥更喜欢称之为滤镜）而后者为浮雕遮罩滤镜
 *
 *          25.setRasterizer (Rasterizer rasterizer)
 *              设置光栅   该方法同样不支持HW在API 21中遗弃了
 *
 *          26.setPathEffect(PathEffect effect)
 *              设置路径效果 PathEffect跟上面的很多类一样没有具体的实现，但是其有六个子类
 *              PathEffect、CornerPathEffect、DiscretePathEffect、DashPathEffect、PathDashPathEffect、ComposePathEffect、SumPathEffect的效果
 *
 *          27.setStrokeCap(Paint.Cap cap)
 *              该方法用来设置我们画笔的笔触风格
 *              ROUND:表示是圆角的笔触(其实很简单，就像我们现实世界中的笔，如果你用圆珠笔在纸上戳一点，那么这个点一定是个圆，即便很小，它代表了笔的笔触形状，如果我们把一支铅笔笔尖削成方形的，那么画出来的线条会是一条弯曲的“矩形”，这就是笔触的意思)
 *              SQUARE和BUTT
 *
 *          28.setStrokeJoin(Paint.Join join)
 *              用于设置结合处的形态，就像上面的代码中我们虽说是花了一条心电线，但是这条线其实是由无数条小线拼接成的，拼接处的形状就由该方法指定
 *
 *          29.setShadowLayer(float radius, float dx, float dy, int shadowColor)
 *              为我们绘制的图形添加一个阴影层效果
 *              radius表示阴影的扩散半径，而dx和dy表示阴影平面上的偏移值，shadowColor就不说了阴影颜色
 *              跟BlurMaskFilter比起来这方法是不是更简捷呢？但是BlurMaskFilter能做的setShadowLayer却不一定能做到哦！
 *
 */

public class TextPaint3 extends View {

    private static final String TEXT = "This is used by widgets to control text layout. You should not need to use this class directly unless you are implementing your own widget or custom display object, or would be tempted to call Canvas.drawText() directly.";
    private TextPaint mTextPaint; // 文本的画笔
    private StaticLayout mStaticLayout; // 文本布局


    public TextPaint3(Context context) {
        this(context, null);
    }

    public TextPaint3(Context context, AttributeSet attrs) {
        super(context, attrs);

        initPaint();
    }

    private void initPaint() {
        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(50);
        mTextPaint.setColor(Color.BLACK);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mStaticLayout = new StaticLayout(TEXT, mTextPaint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL,
                1.0f, 0.0f, false);
        mStaticLayout.draw(canvas);
    }
}
